#pragma once
#include "RBTree.h"

namespace ape
{
	// map类
	template <class K, class V>
	class map
	{
		// 仿函数operator() 获得key
		struct GetKeyMap
		{
			const K &operator()(const pair<const K, V> &pair)
			{
				return pair.first;
			}
		};

	private:
		RBTree<K, pair<const K, V>, GetKeyMap> _rbtree;

	public:
		// 迭代器均用普通迭代器
		// 但是传参RBTree<K, pair<const K, V>, GetKeyMap> _rbtree; 认定K为const 即只能修改V
		typedef typename RBTree<K, pair<const K, V>, GetKeyMap>::itertaor iterator;

		// begin迭代器
		iterator begin()
		{
			return _rbtree.begin();
		}

		// end迭代器
		iterator end()
		{
			return _rbtree.end();
		}

		// 重载下标运算符[]
		V &operator[](const K &key)
		{
			pair<iterator, bool> pair = _rbtree.Insert(make_pair(key, V()));
			return pair.first->second;
		}

		// 插入函数
		pair<iterator, bool> insert(const pair<const K, V> &pair)
		{
			return _rbtree.Insert(pair);
		}

		// 查找函数
		iterator find(const K &key)
		{
			return _rbtree.Find(key);
		}

		// 编译器自动生成默认构造函数
		map() = default;

		// 迭代器区间构造
		template <class InputIterator>
		map(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				_rbtree.Insert(*first);
				++first;
			}
		}
	};

	/////////////////// 测试 ////////////////////////////////////////

	void test_map1()
	{
		// 插入
		map<string, string> m;
		string a = "Eddie", b = "彭于晏";
		m.insert(make_pair(a, b));
		m.insert(make_pair("Tom", "汤姆"));
		m.insert(make_pair("Jerry", "杰瑞"));
		// 迭代器遍历
		map<string, string>::iterator it = m.begin();
		while (it != m.end())
		{
			cout << it->first << ":" << it->second << endl;
			/*
			it->first = "Ape";
			it->second = "阿猿";
			*/
			++it;
		}
		cout << endl;
		// for循环遍历
		for (auto &e : m)
		{
			cout << e.first << ":" << e.second << endl;
		}
		cout << endl;
	}

	void test_map2()
	{
		string s[] = {"陀螺", "陀螺", "洋娃娃", "陀螺", "洋娃娃", "洋娃娃", "陀螺",
					  "洋娃娃", "悠悠球", "洋娃娃", "悠悠球", "乐高"};
		// 记录次数
		map<string, int> m;
		for (auto &e : s)
		{
			m[e]++;
		}

		// for循环遍历
		for (auto &e : m)
		{
			cout << e.first << ":" << e.second << endl;
		}
	}
}
